This repository has been archived by the owner on May 10, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 441
/
AdsNotificationHandler.swift
90 lines (82 loc) · 3.78 KB
/
AdsNotificationHandler.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
import Foundation
import UIKit
import BraveCore
import SnapKit
import BraveShared
class AdsNotificationHandler: BraveAdsNotificationHandler {
/// An ad was tapped and a URL should be opened
var actionOccured: ((NotificationAd?, RewardsNotification.Action) -> Void)?
/// The ads object
let ads: BraveAds
/// Whether or not we should currently show ads currently based on exteranl
/// factors such as private mode
var canShowNotifications: (() -> Bool)?
/// The controller which we will show notifications on top of
private(set) weak var presentingController: UIViewController?
/// The controller that display, hide and manage notifications
private weak var notificationsPresenter: BraveNotificationsPresenter?
/// Create a handler instance with the given ads instance.
///
/// - note: This method automatically sets `notificationsHandler` on BATBraveAds
/// to itself
init(
ads: BraveAds,
presentingController: UIViewController,
notificationsPresenter: BraveNotificationsPresenter
) {
self.ads = ads
self.notificationsPresenter = notificationsPresenter
self.presentingController = presentingController
self.ads.notificationsHandler = self
}
func showNotification(_ notification: NotificationAd) {
guard let presentingController = presentingController else { return }
let rewardsNotification = RewardsNotification(ad: notification) { [weak self] action in
guard let self = self else { return }
switch action {
case .opened:
self.ads.reportNotificationAdEvent(notification.placementID, eventType: .clicked, completion: { _ in })
case .dismissed:
self.ads.reportNotificationAdEvent(notification.placementID, eventType: .dismissed, completion: { _ in })
case .timedOut:
self.ads.reportNotificationAdEvent(notification.placementID, eventType: .timedOut, completion: { _ in })
case .disliked:
self.ads.reportNotificationAdEvent(notification.placementID, eventType: .dismissed, completion: { _ in })
self.ads.toggleThumbsDown(forAd: notification.creativeInstanceID, advertiserId: notification.advertiserID, segment: notification.segment)
}
self.actionOccured?(notification, action)
}
ads.reportNotificationAdEvent(notification.placementID, eventType: .viewed, completion: { _ in })
notificationsPresenter?.display(notification: rewardsNotification, from: presentingController)
}
func clearNotification(withIdentifier identifier: String) {
notificationsPresenter?.removeNotification(with: identifier)
}
func shouldShowNotifications() -> Bool {
guard let presentingController = presentingController,
let rootVC = presentingController.currentScene?.browserViewController
else { return false }
func topViewController(startingFrom viewController: UIViewController) -> UIViewController {
var top = viewController
if let navigationController = top as? UINavigationController,
let vc = navigationController.visibleViewController {
return topViewController(startingFrom: vc)
}
if let tabController = top as? UITabBarController,
let vc = tabController.selectedViewController {
return topViewController(startingFrom: vc)
}
while let next = top.presentedViewController {
top = next
}
return top
}
let isTopController = presentingController == topViewController(startingFrom: rootVC)
let isTopWindow = presentingController.view.window?.isKeyWindow == true
let canShowAds = canShowNotifications?() ?? true
return isTopController && isTopWindow && canShowAds
}
}